package libra.filter;

import java.util.Map;

import javax.swing.Spring;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;

/**
 * Filter过滤测试控制器
 * 
 * Gateway是基于SpringWebflux开发的
 * 这部分和SpringMVC一样，可以使用SpringMVC的注解编写Controller
 * 本次Gateway&SpringBoot案例为了少起一个boot应用实例，测试方便。
 * 就直接在工程中写了个简易的Controller模拟请求
 */
@RestController
public class FilterController {
	@RequestMapping("addRequestHeader")
	public Object addRequestHeader( ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "addRequestHeader", "header", req.getHeaders());
	}
	@RequestMapping("addRequestHeader/rest/{val}")
	public Object addRequestHeaderRest( @PathVariable("val")String val, ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "addRequestHeader", "header", req.getHeaders(), "val", val);
	}
	
	@RequestMapping("addRequestParameter")
	public Object addRequestParameter( ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "addRequestParameter", "param", req.getQueryParams());
	}
	@RequestMapping("addRequestParameter/rest/{val}")
	public Object addRequestParameterRest( @PathVariable("val")String val, ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "addRequestParameterRest", "param", req.getQueryParams(), "val", val);
	}
	
	@RequestMapping("addResponseHeader")
	public Object addResponseHeader( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		resp.getHeaders().add("addResponseHeader", "addResponseHeader");
		return Map.of("method", "addResponseHeader");
	}
	@RequestMapping("addResponseHeader/rest/{val}")
	public Object addResponseHeaderRest( @PathVariable("val")String val, ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		resp.getHeaders().add("addResponseHeaderRest", "ver1");
		return Map.of("method", "addResponseHeaderRest");
	}
	
	@RequestMapping("removeRequestHeader")
	public Object removeRequestHeader( ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "removeRequestHeader", "header", req.getHeaders());
	}
	
	@RequestMapping("removeRequestParameter")
	public Object removeRequestParameter( ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "removeRequestParameter", "param", req.getQueryParams());
	}
	
	@RequestMapping("removeResponseHeader")
	public Object removeResponseHeader( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		resp.getHeaders().add("removeResponseHeader", "removeResponseHeader");
		return Map.of("method", "removeResponseHeader");
	}
	
	@RequestMapping("dedupeResponseHeader")
	public Object dedupeResponseHeader( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		HttpHeaders headers = resp.getHeaders();
		headers.add("first", "1");
		headers.add("first", "2");
		headers.add("last", "3");
		headers.add("last", "4");
		headers.add("uniqe", "a");
		headers.add("uniqe", "b");
		headers.add("uniqe", "c");
		headers.add("uniqe", "b");
		return Map.of("method", "dedupeResponseHeader");
	}
	
	@RequestMapping("redirectTo")
	public Object redirectTo( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "redirectTo");
	}
	
	@RequestMapping("rewritePath")
	public Object rewritePath( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "rewritePath");
	}
	
	@RequestMapping("setRequestHeader")
	public Object setRequestHeader( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "setRequestHeader", "header", req.getHeaders());
	}
	@RequestMapping("setRequestHeader/rest/{val}")
	public Object setRequestHeaderRest( @PathVariable("val")String val, ServerHttpRequest req, ServerWebExchange serverWebExchange) {
		return Map.of("method", "setRequestHeaderRest", "header", req.getHeaders(), "val", val);
	}
	
	@RequestMapping("setResponseHeader")
	public Object setResponseHeader( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		resp.getHeaders().add("setResponseHeader", "setResponseHeader");
		return Map.of("method", "setResponseHeader");
	}
	@RequestMapping("setResponseHeader/rest/{val}")
	public Object setResponseHeaderRest( @PathVariable("val")String val, ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		resp.getHeaders().add("setResponseHeaderRest", val);
		return Map.of("method", "setResponseHeaderRest");
	}
	@RequestMapping("setRequestHostHeader")
	public Object setRequestHostHeader( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "setRequestHostHeader", "header", req.getHeaders());
	}
	
	@RequestMapping("setStatus")
	public Object setStatus( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "setStatus");
	}
	
	@RequestMapping("setPath/rest/{val}")
	public Object setPath( @PathVariable("val")String val, ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "setPath", "val", val);
	}
	
	@RequestMapping("stripPrefix")
	public Object stripPrefix( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "stripPrefix");
	}
	
	@RequestMapping("prefix/prefixPath")
	public Object prefixPath( ServerHttpRequest req, ServerHttpResponse resp, ServerWebExchange serverWebExchange) {
		return Map.of("method", "PrefixPath");
	}
	
	@RequestMapping("selfBeforeFilter")
	public Object selfBeforeFilter( ServerWebExchange serverWebExchange ) {
		return Map.of("method", "selfBeforeFilter", "header", serverWebExchange.getRequest().getHeaders());
	}
	
	@RequestMapping("outterSelfBeforeFilter")
	public Object outterSelfBeforeFilter( ServerWebExchange serverWebExchange ) {
		return Map.of("method", "outterSelfBeforeFilter", 
				"header", serverWebExchange.getRequest().getHeaders(),
				"param", serverWebExchange.getRequest().getQueryParams() );
	}
}
